﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Complex
    {
        private double real;
        private double imag;

        public double Real
        {
            get { return real; }
            set { real = value; }
        }
        public double Imag
        {
            get { return imag; }
            set { imag = value; }
        }

        public Complex()
        {
            this.real = 0;
            this.imag = 0;
        }
        public Complex(double r, double im)
        {
            this.real = r;
            this.imag = im;
        }

        public static Complex operator -(Complex c1, Complex c2)
        {
            double r = c1.real - c2.real;
            double im = c1.imag - c2.imag;
            return new Complex(r, im);
        }

        public static Complex operator +(Complex c1, Complex c2)
        {
            double r = c1.real + c2.real;
            double im = c1.imag + c2.imag;
            return new Complex(r, im);
        }
        // a+ib 
        //c+id
        //ac-bd + i(ad+cb)
        public static Complex operator *(Complex c1, Complex c2)
        {
            double r = c1.real * c2.real - c1.imag * c2.imag;
            double im = c1.imag * c2.real + c1.real * c2.imag;
            return new Complex(r, im);
        }

        public static Complex operator /(Complex c1, Complex c2)
        {
            double div = (c1.real * c1.real) + (c1.imag * c1.imag);
            Complex tmp = new Complex();
            tmp.real = (c1.real * c2.real) + (c1.imag * c2.imag);
            tmp.real /= div;
            tmp.imag = (c1.imag * c2.real) - (c1.real * c2.imag);
            tmp.imag /= div;
            return tmp;
        }
        public void toString()
        {
            Console.WriteLine("{0} + i*{1}",this.real,this.imag);
        }
        public static void Main(string[] args) 
        {
            Complex c1 = new Complex(1, 3);
            Complex c2 = new Complex(2, 4);
            c1.toString();
        }
        public static explicit operator double(Complex Complex)
        {
            if (Complex.imag == 0)
                return (double)(Complex.real + Complex.imag);
            else
                return double.NaN;
        }

        public static implicit operator Complex(double value)
        {
            double r = value;
            return new Complex(value, 0);
        }

        public double this[int index]
        {
            get
            {
                if ((index >= 0) && (index < 2))
                {
                    if (index == 0)
                        return real;
                    else
                        return imag;
                }
                else
                {
                    throw new IndexOutOfRangeException(String.Format(
                    "Index {0} is invalid!", index));
                }
            }
            set
            {
                if ((index < 0) || (index > 1))
                {
                    throw new IndexOutOfRangeException(String.Format(
                        "Index {0} is invalid!", index));
                }
                else if (index == 0)
                    this[index] = real;
                else
                    this[index] = imag;
            }
        }
    }
}
